package es.uma.scgt.controlador;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import es.uma.scgt.autenticacion.UserDetailsImpl;
import es.uma.scgt.dao.EquipoDao;
import es.uma.scgt.dao.PeticionDao;
import es.uma.scgt.dao.TareaDao;
import es.uma.scgt.dao.UsuarioDao;
import es.uma.scgt.dao.HistoricoDao;
import es.uma.scgt.modelo.Equipo;
import es.uma.scgt.modelo.Fase;
import es.uma.scgt.modelo.FaseP;
import es.uma.scgt.modelo.Historico;
import es.uma.scgt.modelo.Peticion;
import es.uma.scgt.modelo.Prioridad;
import es.uma.scgt.modelo.Tarea;
import es.uma.scgt.modelo.Usuario;

@Controller
public class TareaControlador {

	private static final String PAGINA_CRUD_TAREA = "CrudTarea";
	private static final String PARAM_PETICIONES_EQUIPO_LIST = "PeticionesMiEquipo";
	private static final String PARAM_PETICIONES_CON_TAREA_LIST = "PeticionesConTarea";
	private static final String PARAM_TAREAS_MIEQUIPO_LIST = "TareasMiEquipo";
	private static final String PAGINA_CRUD_ESTADO_TAREA = "CrudTareaFases";
	private static final String PARAM_TAREAS_MIEQUIPO_PENDIENTES = "tareasPendientes";
	private static final String PARAM_TAREAS_MIEQUIPO_DESARROLLO = "tareasDesarrollo";
	private static final String PARAM_TAREAS_MIEQUIPO_TEST = "tareasTest";
	private static final String PARAM_TAREAS_MIEQUIPO_FIN = "tareasFinalizadas";

	@Autowired
	private PeticionDao peticionDao;
	@Autowired
	private TareaDao tareaDao;
	@Autowired
	private UsuarioDao usuarioDao;
	@Autowired
	private EquipoDao equipoDao;
	@Autowired
	private HistoricoDao historicoDao;

	@RequestMapping("/CrudTarea")
	@Transactional
	public String iniCrudTarea(ModelMap model) {

		UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		List<Equipo> listaEquipos = userDetails.getListaEquipos();

		model.addAttribute(PARAM_PETICIONES_EQUIPO_LIST, peticionDao.getPeticionesMiEquipo(listaEquipos));

		return PAGINA_CRUD_TAREA;
	}

	@RequestMapping("/CrudTareaFases")
	@Transactional
	public String iniCrudTareaFases(ModelMap model) {
		UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		List<Equipo> listaEquipos = userDetails.getListaEquipos();

		List<Integer> listaEquipoId = new ArrayList<Integer>();

		for (Equipo equipo : listaEquipos) {
			listaEquipoId.add(equipo.getId());
		}

		List<Integer> listaUsuarioId = equipoDao.usuariosXEquipo(listaEquipoId);
		List<Usuario> usuarios = new ArrayList<Usuario>();
		for (Integer usuarioId : listaUsuarioId) {
			Usuario usuarioItem = new Usuario();
			usuarioItem.setId(usuarioId);
			usuarios.add(usuarioItem);
		}

		model.addAttribute(PARAM_TAREAS_MIEQUIPO_LIST, tareaDao.getTareaMiEquipo(usuarios));
		model.addAttribute(PARAM_TAREAS_MIEQUIPO_PENDIENTES, tareaDao.getTareaPendienteMiEquipo(usuarios));
		model.addAttribute(PARAM_TAREAS_MIEQUIPO_DESARROLLO, tareaDao.getTareaDesarrolloMiEquipo(usuarios));
		model.addAttribute(PARAM_TAREAS_MIEQUIPO_TEST, tareaDao.getTareaTestMiEquipo(usuarios));
		model.addAttribute(PARAM_TAREAS_MIEQUIPO_FIN, tareaDao.getTareaFinalizadaMiEquipo(usuarios));

		return PAGINA_CRUD_ESTADO_TAREA;

	}

	@RequestMapping("/CompletarPeticion")
	@Transactional
	public String completarPeticion(ModelMap model, @RequestParam(required = false, value = "peticionIdCompletarPeticion") Integer peticionId) {

		if (peticionId != null) {
			Peticion cambiaFase = null;
			cambiaFase = new Peticion();
			cambiaFase = peticionDao.encuentraPeticionPorId(peticionId);
			cambiaFase.setFase(FaseP.P);
			peticionDao.peticionEnviar(cambiaFase);

		}

		return iniCrudTarea(model);
	}

	// Eliminar Tarea

	@RequestMapping("/EliminarTarea")
	@Transactional
	public String eliminarTarea(ModelMap model, @RequestParam("tareaidE") Integer tareaIdE) {

		JOptionPane.showMessageDialog(null, tareaIdE);

		if (tareaIdE != null) {
			tareaDao.eliminarTarea(tareaIdE);
		}

		return iniCrudTarea(model);
	}

	@RequestMapping("/NuevaTarea")
	@Transactional
	public String nuevaTarea(ModelMap model, @RequestParam(required = false, value = "PTrasnfT") Integer pTrasnfT, @RequestParam("tareaid") Integer tareaId,
			@RequestParam("fCreacionT") String fCreacion, @RequestParam("tituloTarea") String titulo, @RequestParam("prioridadTarea") String prioridadTarea,
			@RequestParam("tareaDescripcion") String descripcion, @RequestParam("fEntregaT") String fEntrega) {

		Prioridad prioridad = Prioridad.fromString(prioridadTarea);
		Tarea tmpTarea = new Tarea();
		Historico tmpHistorico = new Historico();
		UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

		
		
		// if (pTrasnfT != null) {
		Date fEntregaDate;
		Date fCreacionDate;
		
		String resultado;
		
		try {
			if (fCreacion != null && !fCreacion.isEmpty()) {
				fEntregaDate = new SimpleDateFormat("dd/MM/yyyy").parse(fCreacion);
			} else {
				fEntregaDate = null;
			}
			if (fEntrega != null && !fEntrega.isEmpty()) {
				fCreacionDate = new SimpleDateFormat("dd/MM/yyyy").parse(fEntrega);
			} else {
				fCreacionDate = null;
			}
			

		} catch (ParseException e) {
			e.printStackTrace();
			fEntregaDate = null;
			fCreacionDate = null;
		}
		
		if (tareaId == null){//Si es nueva
			tmpTarea.setUsuario(usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId()));// solo si es una nueva tarea
			tmpHistorico.setUsuario(usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId()));
			tmpHistorico.setUsuarioModificacion(usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId()));
			
			// Es una tarea que viene de Inbox Tarea
			if (pTrasnfT != null) {
				rellenarTarea(tareaId, descripcion, fCreacionDate, titulo, prioridad, fEntregaDate, pTrasnfT, tmpTarea);
				tmpTarea.setFase(Fase.PENDIENTE);
				tareaDao.nuevaTarea(tmpTarea);
				//Anadimos tarea al historico
				rellenarHistorico(tmpTarea, prioridad, tmpTarea.getFase(), tmpHistorico);
				historicoDao.addHistorico(tmpHistorico);
			} else {
				rellenarTareaSinPeticion(tareaId, descripcion, fCreacionDate, titulo, prioridad, fEntregaDate, tmpTarea);
				tmpTarea.setFase(Fase.PENDIENTE);
				
				tareaDao.nuevaTarea(tmpTarea);
				//Anadimos tarea al historico
				rellenarHistorico(tmpTarea, prioridad, tmpTarea.getFase(), tmpHistorico);
				historicoDao.addHistorico(tmpHistorico);
				
			}
		}else{// Si es un editar
			//Conseguir datos de la tarea editada. Encuentra Tarea x Id
			Tarea tEditada = new Tarea();
			tEditada = tareaDao.encuentraTareaxId(tareaId);
			
			Usuario usuarioConectado = new Usuario();
			usuarioConectado = usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId());
			
			
			if (tEditada.getPrioridad() != prioridad){
				//Si se ha cambiado la prioridad
				rellenarHistorico(tEditada, prioridad, tEditada.getFase(), tmpHistorico);
				tmpHistorico.setUsuarioModificacion(usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId()));
				tmpHistorico.setUsuario(tEditada.getUsuario());
				historicoDao.addHistorico(tmpHistorico);
			}
			
			//tmpHistorico.setUsuarioModificacion(usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId()));
			
			if (pTrasnfT != null){
				rellenarTarea(tareaId, descripcion, fCreacionDate, titulo, prioridad, fEntregaDate, pTrasnfT, tEditada);
				tEditada.setFase(Fase.PENDIENTE);
				tEditada.setUsuario(usuarioConectado);
				tareaDao.nuevaTarea(tEditada);
			}else{
				rellenarTareaSinPeticion(tareaId, descripcion, fCreacionDate, titulo, prioridad, fEntregaDate, tEditada);
				tEditada.setFase(Fase.PENDIENTE);
				tEditada.setUsuario(usuarioConectado);
				tareaDao.nuevaTarea(tEditada);
			}
		}
		
		

		resultado = iniCrudTareaFases(model);
		return resultado;
	}

	@RequestMapping("/CrearTarea")
	@Transactional
	public String crearTarea(ModelMap model, @RequestParam(required = false, value = "PTrasnfT") Integer pTrasnfT) {
		// Mirar en Tareas si ya existe una tarea con la peticion seleccionada

		if (pTrasnfT != null) {
			List<Tarea> listaTareas = tareaDao.existeTareaPorPeticion(pTrasnfT);
			model.addAttribute(PARAM_PETICIONES_CON_TAREA_LIST, listaTareas);
		}

		return PARAM_PETICIONES_CON_TAREA_LIST;
	}

	@RequestMapping("/PasarTarea")
	@Transactional
	public String pasarTarea(ModelMap model, @RequestParam("AFase") String aFase) {
		// Cambiar el estado de la Tarea

		return null;
	}

	// Funciones auxiliares

	private void rellenarTarea(Integer tareaid, String descripcion, Date fCreacion, String titulo, Prioridad prioridad, Date fEntrega, Integer peticionId, Tarea nuevaTarea) {

		nuevaTarea.setId(tareaid);
		nuevaTarea.setDescripcion(descripcion);
		nuevaTarea.setFechaAlta(fCreacion);
		nuevaTarea.setTitulo(titulo);
		nuevaTarea.setPrioridad(prioridad);
		nuevaTarea.setFechaFin(fEntrega);
		nuevaTarea.setPeticion(peticionDao.encuentraPeticionPorId(peticionId));

	}
	
	private void rellenarHistorico(Tarea tarea, Prioridad prioridad, Fase fase, Historico addHistorico){
		
		Date fechaModificacion = new Date();
		
		addHistorico.setTarea(tarea);
		addHistorico.setPrioridad(prioridad);
		addHistorico.setFase(fase);
		addHistorico.setFechaModificacion(fechaModificacion);
		
	}

	private void rellenarFase(Integer destino, Tarea tarea) {
		Integer tareaId;
		Integer peticionId;
		Integer tConPeticionId, tFConPeticionId;

		if (destino == 0) {
			// Fase Pendiente
			tarea.setFase(Fase.PENDIENTE);

		} else if (destino == 1) {
			// Fase Desarrollo
			tarea.setFase(Fase.DESARROLLO);

		} else if (destino == 2) {
			// Fase Test
			tarea.setFase(Fase.TEST);
		} else {
			// Fase Finalizado
			// Comprobamos si tiene peticion

			// Cambiamos fase
			tareaId = tarea.getId();
			Peticion peticion = new Peticion();

			peticion = tarea.getPeticion();

			if (peticion != null) {
				peticionId = peticion.getId();
				// Contar cuantas peticiones con la peticionId tiene la fase de
				// la Tarea FINALIZADO

				tFConPeticionId = tareaDao.contarTareasFConPeticion(peticionId);
				// Contar cuantas peticiones con la peticionId hay

				tConPeticionId = tareaDao.contarTareasConPeticion(peticionId);

				if ((tFConPeticionId + 1) == tConPeticionId) {
					peticion.setFase(FaseP.F);
					peticionDao.peticionEnviar(peticion);
				}

			}

			tarea.setFase(Fase.FINALIZADO);
		}
	}

	private void rellenarTareaSinPeticion(Integer tareaid, String descripcion, Date fCreacion, String titulo, Prioridad prioridad, Date fEntrega, Tarea nuevaTarea) {

		nuevaTarea.setId(tareaid);
		nuevaTarea.setDescripcion(descripcion);
		nuevaTarea.setFechaAlta(fCreacion);
		nuevaTarea.setTitulo(titulo);
		nuevaTarea.setPrioridad(prioridad);
		nuevaTarea.setFechaFin(fEntrega);

	}

	@RequestMapping("/cambiarFaseT")
	@Transactional
	public @ResponseBody
	String cambiarFaseT(@RequestParam("origen") Integer origen, @RequestParam("destino") Integer destino, @RequestParam("item") Integer item) {
		//Tarea
		Tarea tarea = new Tarea();
		Historico historico = new Historico();
		UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		
		tarea = tareaDao.encuentraTareaxId(item);
		// Actualizamos fase
		rellenarFase(destino, tarea);
		tareaDao.nuevaTarea(tarea);
		//Insertamos datos en Historico
		rellenarHistorico(tarea, tarea.getPrioridad(), tarea.getFase(), historico);
		historico.setUsuario(tarea.getUsuario());
		historico.setUsuarioModificacion(usuarioDao.encuentraUsuarioPorId(userDetails.getUsuarioId()));
		historicoDao.addHistorico(historico);
		return "OK";
	}

}
